home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / net / RCS / res_comp.c,v < prev    next >
Text File  |  1989-05-18  |  7KB  |  370 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     89.05.18.17.14.49;  author rab;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     88.06.20.09.57.16;  author ouster;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24. 1.2
  25. log
  26. @Added forward declarations for static functions.
  27. @
  28. text
  29. @/*
  30.  * Copyright (c) 1985 Regents of the University of California.
  31.  * All rights reserved.
  32.  *
  33.  * Redistribution and use in source and binary forms are permitted
  34.  * provided that this notice is preserved and that due credit is given
  35.  * to the University of California at Berkeley. The name of the University
  36.  * may not be used to endorse or promote products derived from this
  37.  * software without specific prior written permission. This software
  38.  * is provided ``as is'' without express or implied warranty.
  39.  */
  40.  
  41. #if defined(LIBC_SCCS) && !defined(lint)
  42. static char sccsid[] = "@@(#)res_comp.c    6.13 (Berkeley) 3/13/88";
  43. #endif /* LIBC_SCCS and not lint */
  44.  
  45. #include <sys/types.h>
  46. #include <stdio.h>
  47. #include <arpa/nameser.h>
  48.  
  49. static int dn_find();
  50.  
  51.  
  52. /*
  53.  * Expand compressed domain name 'comp_dn' to full domain name.
  54.  * 'msg' is a pointer to the begining of the message,
  55.  * 'eomorig' points to the first location after the message,
  56.  * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
  57.  * Return size of compressed name or -1 if there was an error.
  58.  */
  59. int
  60. dn_expand(msg, eomorig, comp_dn, exp_dn, length)
  61.     u_char *msg, *eomorig, *comp_dn, *exp_dn;
  62.     int length;
  63. {
  64.     register u_char *cp, *dn;
  65.     register int n, c;
  66.     u_char *eom;
  67.     int len = -1, checked = 0;
  68.  
  69.     dn = exp_dn;
  70.     cp = comp_dn;
  71.     eom = exp_dn + length - 1;
  72.     /*
  73.      * fetch next label in domain name
  74.      */
  75.     while (n = *cp++) {
  76.         /*
  77.          * Check for indirection
  78.          */
  79.         switch (n & INDIR_MASK) {
  80.         case 0:
  81.             if (dn != exp_dn) {
  82.                 if (dn >= eom)
  83.                     return (-1);
  84.                 *dn++ = '.';
  85.             }
  86.             if (dn+n >= eom)
  87.                 return (-1);
  88.             checked += n + 1;
  89.             while (--n >= 0) {
  90.                 if ((c = *cp++) == '.') {
  91.                     if (dn+n+1 >= eom)
  92.                         return (-1);
  93.                     *dn++ = '\\';
  94.                 }
  95.                 *dn++ = c;
  96.                 if (cp >= eomorig)    /* out of range */
  97.                     return(-1);
  98.             }
  99.             break;
  100.  
  101.         case INDIR_MASK:
  102.             if (len < 0)
  103.                 len = cp - comp_dn + 1;
  104.             cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
  105.             if (cp < msg || cp >= eomorig)    /* out of range */
  106.                 return(-1);
  107.             checked += 2;
  108.             /*
  109.              * Check for loops in the compressed name;
  110.              * if we've looked at the whole message,
  111.              * there must be a loop.
  112.              */
  113.             if (checked >= eomorig - msg)
  114.                 return (-1);
  115.             break;
  116.  
  117.         default:
  118.             return (-1);            /* flag error */
  119.         }
  120.     }
  121.     *dn = '\0';
  122.     if (len < 0)
  123.         len = cp - comp_dn;
  124.     return (len);
  125. }
  126.  
  127. /*
  128.  * Compress domain name 'exp_dn' into 'comp_dn'.
  129.  * Return the size of the compressed name or -1.
  130.  * 'length' is the size of the array pointed to by 'comp_dn'.
  131.  * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
  132.  * is a pointer to the beginning of the message. The list ends with NULL.
  133.  * 'lastdnptr' is a pointer to the end of the arrary pointed to
  134.  * by 'dnptrs'. Side effect is to update the list of pointers for
  135.  * labels inserted into the message as we compress the name.
  136.  * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
  137.  * is NULL, we don't update the list.
  138.  */
  139. int
  140. dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
  141.     u_char *exp_dn, *comp_dn;
  142.     int length;
  143.     u_char **dnptrs, **lastdnptr;
  144. {
  145.     register u_char *cp, *dn;
  146.     register int c, l;
  147.     u_char **cpp, **lpp, *sp, *eob;
  148.     u_char *msg;
  149.  
  150.     dn = exp_dn;
  151.     cp = comp_dn;
  152.     eob = cp + length;
  153.     if (dnptrs != NULL) {
  154.         if ((msg = *dnptrs++) != NULL) {
  155.             for (cpp = dnptrs; *cpp != NULL; cpp++)
  156.                 ;
  157.             lpp = cpp;    /* end of list to search */
  158.         }
  159.     } else
  160.         msg = NULL;
  161.     for (c = *dn++; c != '\0'; ) {
  162.         /* look to see if we can use pointers */
  163.         if (msg != NULL) {
  164.             if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
  165.                 if (cp+1 >= eob)
  166.                     return (-1);
  167.                 *cp++ = (l >> 8) | INDIR_MASK;
  168.                 *cp++ = l % 256;
  169.                 return (cp - comp_dn);
  170.             }
  171.             /* not found, save it */
  172.             if (lastdnptr != NULL && cpp < lastdnptr-1) {
  173.                 *cpp++ = cp;
  174.                 *cpp = NULL;
  175.             }
  176.         }
  177.         sp = cp++;    /* save ptr to length byte */
  178.         do {
  179.             if (c == '.') {
  180.                 c = *dn++;
  181.                 break;
  182.             }
  183.             if (c == '\\') {
  184.                 if ((c = *dn++) == '\0')
  185.                     break;
  186.             }
  187.             if (cp >= eob)
  188.                 return (-1);
  189.             *cp++ = c;
  190.         } while ((c = *dn++) != '\0');
  191.         /* catch trailing '.'s but not '..' */
  192.         if ((l = cp - sp - 1) == 0 && c == '\0') {
  193.             cp--;
  194.             break;
  195.         }
  196.         if (l <= 0 || l > MAXLABEL)
  197.             return (-1);
  198.         *sp = l;
  199.     }
  200.     if (cp >= eob)
  201.         return (-1);
  202.     *cp++ = '\0';
  203.     return (cp - comp_dn);
  204. }
  205.  
  206. /*
  207.  * Skip over a compressed domain name. Return the size or -1.
  208.  */
  209. int
  210. dn_skipname(comp_dn, eom)
  211.     u_char *comp_dn, *eom;
  212. {
  213.     register u_char *cp;
  214.     register int n;
  215.  
  216.     cp = comp_dn;
  217.     while (cp < eom && (n = *cp++)) {
  218.         /*
  219.          * check for indirection
  220.          */
  221.         switch (n & INDIR_MASK) {
  222.         case 0:        /* normal case, n == len */
  223.             cp += n;
  224.             continue;
  225.         default:    /* illegal type */
  226.             return (-1);
  227.         case INDIR_MASK:    /* indirection */
  228.             cp++;
  229.         }
  230.         break;
  231.     }
  232.     return (cp - comp_dn);
  233. }
  234.  
  235. /*
  236.  * Search for expanded name from a list of previously compressed names.
  237.  * Return the offset from msg if found or -1.
  238.  * dnptrs is the pointer to the first name on the list,
  239.  * not the pointer to the start of the message.
  240.  */
  241. static int
  242. dn_find(exp_dn, msg, dnptrs, lastdnptr)
  243.     u_char *exp_dn, *msg;
  244.     u_char **dnptrs, **lastdnptr;
  245. {
  246.     register u_char *dn, *cp, **cpp;
  247.     register int n;
  248.     u_char *sp;
  249.  
  250.     for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
  251.         dn = exp_dn;
  252.         sp = cp = *cpp;
  253.         while (n = *cp++) {
  254.             /*
  255.              * check for indirection
  256.              */
  257.             switch (n & INDIR_MASK) {
  258.             case 0:        /* normal case, n == len */
  259.                 while (--n >= 0) {
  260.                     if (*dn == '\\')
  261.                         dn++;
  262.                     if (*dn++ != *cp++)
  263.                         goto next;
  264.                 }
  265.                 if ((n = *dn++) == '\0' && *cp == '\0')
  266.                     return (sp - msg);
  267.                 if (n == '.')
  268.                     continue;
  269.                 goto next;
  270.  
  271.             default:    /* illegal type */
  272.                 return (-1);
  273.  
  274.             case INDIR_MASK:    /* indirection */
  275.                 cp = msg + (((n & 0x3f) << 8) | *cp);
  276.             }
  277.         }
  278.         if (*dn == '\0')
  279.             return (sp - msg);
  280.     next:    ;
  281.     }
  282.     return (-1);
  283. }
  284.  
  285. /*
  286.  * Routines to insert/extract short/long's. Must account for byte
  287.  * order and non-alignment problems. This code at least has the
  288.  * advantage of being portable.
  289.  *
  290.  * used by sendmail.
  291.  */
  292.  
  293. u_short
  294. _getshort(msgp)
  295.     u_char *msgp;
  296. {
  297.     register u_char *p = (u_char *) msgp;
  298. #ifdef vax
  299.     /*
  300.      * vax compiler doesn't put shorts in registers
  301.      */
  302.     register u_long u;
  303. #else
  304.     register u_short u;
  305. #endif
  306.  
  307.     u = *p++ << 8;
  308.     return ((u_short)(u | *p));
  309. }
  310.  
  311. u_long
  312. _getlong(msgp)
  313.     u_char *msgp;
  314. {
  315.     register u_char *p = (u_char *) msgp;
  316.     register u_long u;
  317.  
  318.     u = *p++; u <<= 8;
  319.     u |= *p++; u <<= 8;
  320.     u |= *p++; u <<= 8;
  321.     return (u | *p);
  322. }
  323.  
  324. void
  325. putshort(s, msgp)
  326.     register u_short s;
  327.     register u_char *msgp;
  328. {
  329.  
  330.     msgp[1] = s;
  331.     msgp[0] = s >> 8;
  332.     return;
  333. }
  334.  
  335. void
  336. putlong(l, msgp)
  337.     register u_long l;
  338.     register u_char *msgp;
  339. {
  340.  
  341.     msgp[3] = l;
  342.     msgp[2] = (l >>= 8);
  343.     msgp[1] = (l >>= 8);
  344.     msgp[0] = l >> 8;
  345.     return;
  346. }
  347. @
  348.  
  349.  
  350. 1.1
  351. log
  352. @Initial revision
  353. @
  354. text
  355. @d21 1
  356. d23 1
  357. d31 1
  358. d111 1
  359. d181 1
  360. d213 1
  361. a213 1
  362. static
  363. d296 1
  364. a296 1
  365.  
  366. d304 1
  367. d307 1
  368. d317 1
  369. @
  370.